import datetime
import warnings
import sys
import pandas as pd
import talib as tl
from hs_udata import set_token, stock_quote_daily, stock_quote_daily_list

warnings.filterwarnings("ignore")

# f = open('print.txt', 'w+', encoding="UTF-8")
# sys.stdout = f
# sys.stderr = f  # redirect std err, if necessary

MA1 = 5
MA2 = 10
num = 100

nowDate = ""  # 当前日期
Money = 100000.0  # 钱包
nowData = {}  # 当前股价数据
isCross = 0  # 是否突破  0否 -1跌破日均  1突破日均
Holding = 0  # 持股数量
isBuy = 0  # 是否购买
isSell = 0  # 是否卖出
daysNum = 0  # 记录天数

buyDays = 0  # 记录待购买日期
sellDays = 0  # 记录待出售日期

isUpAvg = False  # 是否高于日均

stock_code = "600570.SH"
set_token(token='ruXPpxAnX4-5DOF7SXgKOuI4y7WOtBPVXqE79Nj2q30dHluNv6Hd-ylE-JwynvBZ')  # 注册后，获取并替换token
data = stock_quote_daily_list(en_prod_code=stock_code, begin_date='2021-08-01',
                              end_date='2022-05-10', adjust_way='1')

nowDate = data.trading_date.values[-1]
nowDate = datetime.datetime.strptime(nowDate, '%Y-%m-%d')


# 上穿信号
# values上穿avg，返回上穿位置索引
def upCross(values, window):
    avg = tl.MA(values, window)
    assert len(values) == len(avg), '上穿信号输入维度不相等'
    assert len(values) > 1, '上穿信号长度至少为2'
    res = []
    for i in range(window, len(values)):
        if values[i - 1] < avg[i - 1] and values[i] > avg[i]:
            val = [values[i], i]
            res.append(val)

    return res


# 下穿信号
# values下穿avg，返回下穿位置索引
def downCross(values, window):
    avg = tl.MA(values, window)
    assert len(values) == len(avg), '上穿信号输入维度不相等'
    assert len(values) > 1, '上穿信号长度至少为2'
    res = []
    for i in range(window, len(values)):
        if values[i - 1] > avg[i - 1] and values[i] < avg[i]:
            val = [values[i], i]
            res.append(val)

    return res


def Init(data_i):
    global data

    data = data.append(data_i, ignore_index=True)

    dataReshape = data[['trading_date', 'open_price', 'high_price', 'low_price', 'close_price', 'business_amount']]
    dataReshape[['open_price', 'high_price', 'low_price', 'close_price', 'business_amount']] = dataReshape[
        ['open_price', 'high_price', 'low_price', 'close_price', 'business_amount']].astype(float)  # 将价格数据类型转为浮点数

    global isBuy, isSell, isCross, Holding, Money, isUpAvg
    isCross = 0
    avg = tl.MA(dataReshape.close_price.values[-num:], MA2)
    if dataReshape.close_price.values[-2] < avg[-2] and dataReshape.close_price.values[-1] > avg[-1]:  # 突破
        print("↑↑↑↑突破↑↑↑↑")
        isCross = 1

    if dataReshape.close_price.values[-2] > avg[-2] and dataReshape.close_price.values[-1] < avg[-1]:  # 跌破
        print("↓↓↓↓跌破↓↓↓↓")
        isCross = -1

    if dataReshape.close_price.values[-1] < avg[-1]:
        isUpAvg = False
        print("<<<<低于日均<<<<")
    else:
        isUpAvg = True
        print(">>>>高于日均>>>>")

    role1()

    print("当前日期：", nowDate, "  钱包：", Money, "  天数：", daysNum, "  持股：", Holding, "  总资产：",
          Money + Holding * nowData.open_price.values.astype(float))


def buy():
    global nowDate, Money, daysNum, Holding, nowData, isBuy, isSell
    Holding += Money // nowData.open_price.values.astype(float)  # 全部买入 计算持股
    Money = Money % nowData.open_price.values.astype(float)  # 计算剩余金额
    print("【已收购】")


def sell():
    global nowDate, Money, daysNum, Holding, nowData, isBuy, isSell
    Money += Holding * nowData.open_price.values.astype(float)  # 全部卖出
    Holding = 0
    print("【已出售】")


def role1():
    global buyDays, sellDays
    if buyDate == 0 and isCross == -1:  # 购买日期小于天数  并且  有跌破
        buyDate = daysNum + 5  # 设置下次购买日期
        print("预计:", buyDate, "日购买")
    if buyDate >= daysNum and isUpAvg == True:  # 购买日期未到  并且  高于日均
        print("【取消购买】")
        buyDate = 0  # 重置购买日期
    if buyDate == daysNum and daysNum != 0:  # 收购  重置购买日期
        buyDate = 0
        buy()

    if sellDate == 0 and isCross == 1:  # 出售日期小于天数  并且  有突破
        sellDate = daysNum + 5  # 设置下次出售日期
        print("预计:", sellDate, "日出售")
    if sellDate >= daysNum and isUpAvg == False:  # 出售日期未到  并且  低于日均
        print("【取消出售】")
        sellDate = 0  # 重置出售日期
    if sellDate == daysNum and daysNum != 0:  # 出售  重置购买日期
        sellDate = 0
        sell()


while True:
    nowDate += datetime.timedelta(days=1)  # 日期变量自增
    if datetime.datetime.now().strftime("%Y-%m-%d") <= nowDate.strftime("%Y-%m-%d"): break  # 如果是当日 则退出

    nowData = stock_quote_daily(en_prod_code=stock_code, trading_date=nowDate.strftime('%Y%m%d'), adjust_way=1)
    if nowData.turnover_status.values == '交易':
        print("-----------------------------------------------------------------------------------")
        daysNum += 1
        Init(nowData)
        print("-----------------------------------------------------------------------------------")
